<?php

/**
 *
 * Copyright (c) 2011 Tomáš Holub (tomas.holub@webadvice.cz)
 * 
 * @author Tomáš Holub (tomas.holub@webadvice.cz)
 * @package OverFishCMS
 */

namespace OverFish\Model\Mappers;

use Nette;
use OverFish;
use OverFish\Model\Entities\Article as ArticleEntity;

class Article extends Nette\Object implements OverFish\Model\IMapper {

    private $conn;

    public function __construct(\DibiConnection $conn) {
        $this->conn = $conn;
    }
    
    public function delete($item) {
        $this->conn->delete('page')
            ->where('id = %i', $item->getId())->execute();
    }
    
    public function save($item) {

        if ($item->getId() === NULL) { // insert
            $data = $this->itemToData($item); // vytáhne data z entity a vrátí jako pole
            $data["page"]["x_created"] = new \DateTime;
            $id = $this->conn->insert('page', $data["page"])->execute();
            $id = $this->conn->insertId();
            $data["article"]["id_page"] = $id;
            $articleId = $this->conn->insert('article', $data["article"])->execute();
            $this->setIdentity($item, $id);
            
            if ($data["page"]["homepage"] == "y") {
                $this->conn->update("page", array("homepage" => "n"))
                        ->where('id <> %i', $id)->execute();
            } 
        } else { // update
            $data = $this->itemToData($item); // vytáhne data z entity a vrátí jako pole
            // tady se velice hodí logika, která porovná v jakém stavu byla entita při načtení
            // a v jakém je teď, aby se nemuselo posílat všechno, ale to jsou hodně pokročílé funkce
            // a optimalizace se má dělat až když je potřeba, že :)
            $data["article"]["id_page"] = $item->getId();
            
            $data["page"]["x_modified"] = new \DateTime;
            
            $this->conn->update('page', $data["page"])
                ->where('id = %i', $item->getId())->execute();
            
            $this->conn->update('article', $data["article"])
                ->where('id_page = %i', $item->getId())->execute();
            
            if ($data["page"]["homepage"] == "y") {
                $this->conn->update("page", array("homepage" => "n"))
                        ->where('id <> %i', $item->getId())->execute();
            } 
        }
    }
    
    
    public function itemToData($item) {
        $data = array("page" => array(), "article" => array());
        
        $data["page"] = array(
            "type" => $item->getType(),
            "title" => $item->getTitle(),
            "slug" => \Nette\Utils\Strings::webalize($item->getTitle())
        );
        
        if ($item->getHomepage()) {
            $data["page"]["homepage"] = "y";
        } else {
            $data["page"]["homepage"] = "n";
        }
        
        if ($item->getActive()) {
            $data["page"]["active"] = "y";
        } else {
            $data["page"]["active"] = "n";
        }
        
        $data["article"] = array(
            "content" => $item->getContent(),
        );
        
        return $data;
    }
    
    public function find($id) {
        $data = $this->conn->select('page.*, article.content, article.id_page')
                        ->from('page')
                        ->innerJoin('article')->on('page.id = article.id_page')
                        ->where('page.id = %i', $id)->fetch();

        return $this->load($data);
    }

    public function load($data) {
        $item = new ArticleEntity();

        if (!$data) {
            return False;
        }

        $this->setIdentity($item, $data->id);

        unset($data['id']);

        $item->setTitle($data->title);
        $item->setSlug($data->slug);
        $item->setPageId($data->id_page);
        $item->setContent($data->content);
        $item->setWidth($data->width);
        $item->setHeight($data->height);
        $item->setMenuItemId($this->getMenuItemId($item->getId()));
        
        if ($data->active == "y") {
            $item->setActive(True);
        } else {
            $item->setActive(False);
        }
        
        if ($data->homepage == "y") {
            $item->setHomepage(True);
        } else {
            $item->setHomepage(False);
        }
        

        $item->setUser($data->x_user);
        $item->setX_created( new \DateTime($data->x_created));
        
        if ($data->x_modified) {
            $item->setX_modified( new \DateTime($data->x_modified));
        } else {
            $item->setX_modified( new \DateTime($data->x_created));
        }
        
        

        return $item;
    }
    
    function getMenuItemId($pageId) {
        $result = $this->conn->select("id")
                    ->from("menu_item")
                    ->where("id_page = %i", $pageId)->fetch();
        return (!$result) ? Null : $result->id;
    }
    
    function findBy(array $values) {
        
    }

    /** předáš tomu pole hodnot, podle kterých má hledat. Vrátí jednu entitu */
    function findOneBy(array $values) {
        
    }

    /** vrátí všechno */
    function findAll() {
        $items = $this->conn->select('page.*, article.content, article.id_page')->from('page')->innerJoin('article')->on('page.id = article.id_page')->fetchAll();
        
        $objects = array();
        
        foreach ($items as $item) {
            $objects[] = $this->load($item);
        }
        
        return $objects;
    }

    private function setIdentity($item, $id) {
        $item->setId($id);

        return $item;
    }

    public function getAllDataSource() {
        return $this->conn->select('page.*, article.content, article.id_page')->from('page')->innerJoin('article')->on('page.id = article.id_page');
    }

}

